package com.example.dell.assistant;

import android.Manifest;
import android.content.ActivityNotFoundException;
import android.content.Context;
import android.content.Intent;
import android.content.pm.PackageInfo;
import android.content.pm.PackageManager;
import android.graphics.Color;
import android.graphics.drawable.Drawable;
import android.net.ConnectivityManager;
import android.net.NetworkInfo;
import android.net.Uri;
import android.os.Handler;
import android.os.Message;
import android.speech.RecognizerIntent;

import android.speech.tts.TextToSpeech;
import android.support.annotation.Nullable;
import android.support.v4.app.ActivityCompat;
import android.support.v4.content.ContextCompat;
import android.support.v7.app.AppCompatActivity;
import android.os.Bundle;
import android.util.Log;
import android.view.View;
import android.widget.ImageButton;
import android.widget.LinearLayout;
import android.widget.TextView;
import android.widget.Toast;

import com.amap.api.location.AMapLocation;
import com.amap.api.location.AMapLocationClient;
import com.amap.api.location.AMapLocationClientOption;
import com.amap.api.location.AMapLocationListener;
import com.google.gson.Gson;

import org.json.JSONArray;
import org.json.JSONException;
import org.json.JSONObject;

import java.io.BufferedReader;
import java.io.IOException;
import java.io.InputStreamReader;
import java.io.UnsupportedEncodingException;
import java.net.HttpURLConnection;
import java.net.URL;
import java.net.URLEncoder;
import java.security.MessageDigest;
import java.security.NoSuchAlgorithmException;
import java.util.ArrayList;
import java.util.Arrays;
import java.util.List;
import java.util.Locale;

import interfaces.heweather.com.interfacesmodule.bean.Lang;
import interfaces.heweather.com.interfacesmodule.bean.Unit;
import interfaces.heweather.com.interfacesmodule.bean.air.now.AirNow;
import interfaces.heweather.com.interfacesmodule.bean.weather.now.Now;
import interfaces.heweather.com.interfacesmodule.view.HeConfig;
import interfaces.heweather.com.interfacesmodule.view.HeWeather;
import okhttp3.OkHttpClient;
import okhttp3.Request;
import okhttp3.Response;

public class MainActivity extends AppCompatActivity {
    private final int SPEECH_RECOGNITION_CODE = 1;
    private ImageButton button;
    private TextToSpeech textToSpeech = null;//创建自带语音对象
    LinearLayout add;
    //声明定位回调监听器
    private  String CityId;
    String answer;
    //初始化定位
    public AMapLocationClient mLocationClient = null;
    public AMapLocationClientOption mLocationOption=null;
    String detail;
    StringBuilder Show;
    String[] a = null;
    Handler handler = new Handler(){
        @Override
        public void handleMessage(Message msg){
            AddChat((String) msg.obj,1);
            startAuto((String) msg.obj);
        }
    };

    @Override
    protected void onCreate(Bundle savedInstanceState) {
        super.onCreate(savedInstanceState);
        setContentView(R.layout.voice_assistant);
        button = findViewById(R.id.btn_img);
        HeConfig.init("HE2005062114351575","22f120a804d74df6840b5b88b787df6e");
        HeConfig.switchToFreeServerNode();
        initTTS();
        initMap();
        button.setOnClickListener(new View.OnClickListener() {
            @Override
            public void onClick(View v) {
                if (isOnline()) {
                    textToSpeech.stop();//停止之前正在读的语音
                    StartSpeechToText();//开始读新的语音
                } else {
                    Toast.makeText(MainActivity.this, "尚未联网！", Toast.LENGTH_SHORT).show();
                }

            }
        });
    }

    //判断是否联网
    protected boolean isOnline() {
        ConnectivityManager cm = (ConnectivityManager) getSystemService(Context.CONNECTIVITY_SERVICE);
        NetworkInfo netInfo = cm.getActiveNetworkInfo();
        if (netInfo != null && netInfo.isConnectedOrConnecting()) {
            return true;
        } else {
            return false;
        }
    }

    //问答
    private void answer_question(String question){
        answer = "很抱歉没听清，再说一次看看？";
        if(question.contains("华侨大学")){
            //问题 1 ：
            if (question.contains("校庆日")) {
                answer = "华侨大学的校庆日是11月1号。";
            }
            //问题 2 ：
            if (question.contains("几个") & question.contains("校区")) {
                answer = "华侨大学一共有两个校区，分别是泉州校区和厦门校区。";
            }
            //问题 3 && 4 ：
            if ((question.contains("厦门") | question.contains("泉州")) & (question.contains("地址") | question.contains("在哪里"))) {
                if(question.contains("厦门")){
                    answer = "华侨大学厦门校区地址为：福建省厦门市集美大道668号。";
                }
                if(question.contains("泉州")){
                    answer = "华侨大学泉州校区地址为：福建省泉州市丰泽区城华北路269号。";
                }
            }
            //问题 5 ：
            if (question.contains("校长")) {
                answer = "华侨大学的校长是徐西鹏先生。";
            }
            //问题 6 ：
            if (question.contains("部门") & question.contains("管辖")) {
                answer = "华侨大学隶属中央统战部管辖。";
            }
            //问题 7 ：
            if (question.contains("校训")) {
                answer = "华侨大学的校训是：会通中外，并育德才。";
            }
            //问题 8 ：
            if (question.contains("校歌")) {
                answer = "华侨大学的校歌是：《一方沃土》。";
            }
            AddChat(question+"?",0);
            AddChat(answer,1);
            startAuto(answer);
        }
        else if(question.contains("天气")){
            AddChat(question+"?",0);
            getWether();
        }
        else{
            AddChat(question+"?",0);
            TuringAns(question,handler);
        }

    }

    //添加对话框
    public void AddChat(String a,int s) {
        TextView textView = new TextView(this);
        textView.setPadding(10, 10, 10, 10);
        if(s != 0){textView.setBackgroundResource(R.drawable.text);}
        textView.setText(a);
        textView.setTextSize(12);
        textView.setGravity(View.TEXT_ALIGNMENT_CENTER);
        LinearLayout.LayoutParams params = new LinearLayout.LayoutParams(LinearLayout.LayoutParams.WRAP_CONTENT, LinearLayout.LayoutParams.WRAP_CONTENT);
        params.setMargins(30, 15, 30, 15);
        add = findViewById(R.id.main);
        add.addView(textView,params);
    }

    /*
             语音模块开始
     */
    private void initTTS() {
        //实例化自带语音对象
        textToSpeech = new TextToSpeech(this, new TextToSpeech.OnInitListener() {
            @Override
            public void onInit(int status) {
                if (status == textToSpeech.SUCCESS) {
                    //判断是否支持下面两种语言
                    int result1 = textToSpeech.setLanguage(Locale.US);
                    int result2 = textToSpeech.setLanguage(Locale.SIMPLIFIED_CHINESE);
                    boolean a = (result1 == TextToSpeech.LANG_MISSING_DATA || result1 == TextToSpeech.LANG_NOT_SUPPORTED);
                    boolean b = (result2 == TextToSpeech.LANG_MISSING_DATA || result2 == TextToSpeech.LANG_NOT_SUPPORTED);
                } else {
                    Toast.makeText(MainActivity.this, "数据丢失或不支持", Toast.LENGTH_SHORT).show();
                }
            }
        });
    }

    //发声
    private void startAuto(String data) {
        // 设置音调，值越大声音越尖（女生），值越小则变成男声,1.0是常规
        textToSpeech.setPitch(1.0f);
        // 设置语速
        textToSpeech.setSpeechRate(1.0f);
        textToSpeech.speak(data,//输入中文，若不支持的设备则不会读出来
                TextToSpeech.QUEUE_FLUSH, null);
    }

    private void StartSpeechToText() {
        Intent intent = new Intent(RecognizerIntent.ACTION_RECOGNIZE_SPEECH);
        intent.putExtra(RecognizerIntent.EXTRA_LANGUAGE_MODEL, RecognizerIntent.LANGUAGE_MODEL_FREE_FORM);
        try {
            startActivityForResult(intent, SPEECH_RECOGNITION_CODE); // 1
        } catch (ActivityNotFoundException e) {
            Toast.makeText(this, "对不起，没听清！", Toast.LENGTH_SHORT).show();
        }
    }

    protected void onActivityResult(int requestCode, int resultCode, Intent data) {
        super.onActivityResult(requestCode, resultCode, data);
        switch (requestCode) {
            case SPEECH_RECOGNITION_CODE: {
                if (resultCode == RESULT_OK && null != data) {
                    //获取语音数据
                    ArrayList<String> result = data.getStringArrayListExtra(RecognizerIntent.EXTRA_RESULTS); //String
                    //AddChat(result.toString());
                    answer_question(result.get(0));
                }
                break;
            }
        }
    }

    @Override
    protected void onStop() {
        super.onStop();
        textToSpeech.stop(); // 不管是否正在朗读TTS都被打断
        textToSpeech.shutdown(); // 关闭，释放资源
    }
    /*
             语音模块结束
     */

    /*
             获取定位
     */
    private void initMap() {
        //初始化定位
        mLocationClient=new AMapLocationClient(MainActivity.this);
        //设置定位回调监听
        mLocationClient.setLocationListener(mLocationListener);
        mLocationOption = new AMapLocationClientOption();
//设置定位模式为高精度模式，AMapLocationMode.Battery_Saving为低功耗模式，AMapLocationMode.Device_Sensors是仅设备模式
        mLocationOption.setLocationMode(AMapLocationClientOption.AMapLocationMode.Hight_Accuracy);
        mLocationOption.setNeedAddress(true);//设置是否返回地址信息（默认返回地址信息）
        mLocationOption.setOnceLocation(false);//设置是否只定位一次,默认为false
        mLocationOption.setWifiActiveScan(true);//设置是否强制刷新WIFI，默认为强制刷新
        mLocationOption.setMockEnable(false);//设置是否允许模拟位置,默认为false，不允许模拟位置
        mLocationOption.setInterval(15000);//设置定位间隔,单位毫秒,默认为2000ms
        mLocationOption.setOnceLocation(false);//可选，是否设置单次定位默认为false即持续定位
        mLocationOption.setOnceLocationLatest(false); //可选，设置是否等待wifi刷新，默认为false.如果设置为true,会自动变为单次定位，持续定位时不要使用
        mLocationOption.setWifiScan(true); //可选，设置是否开启wifi扫描。默认为true，如果设置为false会同时停止主动刷新，停止以后完全依赖于系统刷新，定位位置可能存在误差
        mLocationOption.setLocationCacheEnable(true); //可选，设置是否使用缓存定位，默认为true
//给定位客户端对象设置定位参数
        mLocationClient.setLocationOption(mLocationOption);
//启动定位
        mLocationClient.startLocation();
    }

    protected void TuringAns(String a, final Handler handler){
        String APIKEY = "be2f963e0f05416b95a2d0044f867da6";
        String INFO = null;
        try {
            INFO = URLEncoder.encode(a, "utf-8");
        } catch (UnsupportedEncodingException e) {
            e.printStackTrace();
        }
        final String getURL = "http://www.tuling123.com/openapi/api?key=" + APIKEY + "&info=" + INFO;
        new Thread(new Runnable() {
            @Override
            public void run() {
                OkHttpClient okHttpClient = new OkHttpClient();
                Request request = new Request.Builder().url(getURL).build();
                try {
                    Response response = okHttpClient.newCall(request).execute();
                    //返回城市列表json数据，信息列表
                    String responseData = response.body().string();
                    JSONObject jsonAns = null;
                    try {
                        jsonAns = new JSONObject(responseData);
                        String jsonAnswer = jsonAns.getString("text");
                        System.out.println("变成json数据的格式：" + jsonAnswer);
                        Message message = new Message();
                        message.obj =jsonAnswer;
                        handler.sendMessage(message);
                    } catch (Exception e) {
                        e.printStackTrace();
                    }
                } catch (IOException e) {
                    e.printStackTrace();
                }
            }
        }).start();
    }
    public AMapLocationListener mLocationListener = new AMapLocationListener(){
        @Override
        public void onLocationChanged(AMapLocation aMapLocation) {
            if (aMapLocation != null) {
                if (aMapLocation.getErrorCode() == 0) {
                    //定位成功回调信息，设置相关消息
                    aMapLocation.getLocationType();//获取当前定位结果来源，如网络定位结果，详见定位类型表
                    aMapLocation.getAccuracy();//获取精度信息
                    //  aMapLocation.getAddress();//地址，如果option中设置isNeedAddress为false，则没有此结果，网络定位结果中会有地址信息，GPS定位不返回地址信息。
                    //  aMapLocation.getCountry();//国家信息
                    //  aMapLocation.getProvince();//省信息
                    //  aMapLocation.getCity();//城市信息
                    //   aMapLocation.getDistrict();//城区信息
                    detail = aMapLocation.getDistrict()+aMapLocation.getStreet();
                    //aMapLocation.getStreet();//街道信息
                        // = aMapLocation.getCityCode();//城市编码
                    //     aMapLocation.getAdCode();//地区编码
                    //获取经纬度
                    double  LongitudeId = aMapLocation.getLongitude();
                    double LatitudeId = aMapLocation.getLatitude();
                    //获取定位城市定位的ID
                    requestCityInfo(LongitudeId,LatitudeId);
                    mLocationClient.stopLocation();//停止定位
                } else {
                    //显示错误信息ErrCode是错误码，errInfo是错误信息，详见错误码表。
                    Log.e("info", "location Error, ErrCode:"
                            + aMapLocation.getErrorCode() + ", errInfo:"
                            + aMapLocation.getErrorInfo());
                }
            }
        }
    };
    public void  requestCityInfo(double longitude,double latitude){
        //这里的key是webapi key
        String cityUrl = "https://search.heweather.net/find?location="+longitude+","+latitude+"&key=b794e0b223a7455fb609db10f0b93ed6";
        sendRequestWithOkHttp(cityUrl);
    }
    //解析根据经纬度获取到的含有城市id的json数据，这里我使用原始的jsonObject与jsonArray来解析，网上也有使用jsonformat插件来，你们也可以那样做
    private void sendRequestWithOkHttp(final String cityUrl) {
        new Thread(new Runnable() {
            @Override
            public void run() {
                OkHttpClient okHttpClient = new OkHttpClient();
                Request request = new Request.Builder().url(cityUrl).build();
                try {
                    Response response = okHttpClient.newCall(request).execute();
                    //返回城市列表json数据，信息列表
                    String responseData = response.body().string();
                    System.out.println("变成json数据的格式："+responseData);
                    JSONObject jsonWeather = null;
                    try {
                        jsonWeather = new JSONObject(responseData);
                        //返回的信息列表
                        JSONArray jsonArray = jsonWeather.getJSONArray("HeWeather6");
                        JSONObject jsonObject = jsonArray.getJSONObject(0);
                        String jsonStatus = jsonObject.getString("status");
                        System.out.println("解析以后的内容："+jsonStatus);
                        if (jsonStatus.equals("ok")){
                            //获取所在城市的id
                            JSONArray jsonBasic = jsonObject.getJSONArray("basic");
                            JSONObject jsonCityId = jsonBasic.getJSONObject(0);
                            CityId = jsonCityId.getString("cid");
                        }
                    } catch (JSONException e) {
                        e.printStackTrace();
                    }
                } catch (IOException e) {
                    e.printStackTrace();
                }
            }
        }).start();
    }

    /*
                 天气查询
     */
    private void getWether() {
        /**
         * 实况天气
         * 实况天气即为当前时间点的天气状况以及温湿风压等气象指数，具体包含的数据：体感温度、
         * 实测温度、天气状况、风力、风速、风向、相对湿度、大气压强、降水量、能见度等。
         * @param context  上下文
         * @param location 地址详解
         * @param lang       多语言，默认为简体中文
         * @param unit        单位选择，公制（m）或英制（i），默认为公制单位
         * @param listener  网络访问回调接口
         */
        HeWeather.getWeatherNow(MainActivity.this, CityId, Lang.CHINESE_SIMPLIFIED, Unit.METRIC, new HeWeather.OnResultWeatherNowBeanListener() {
            public static final String TAG = "he_feng_now";
            @Override
            public void onError(Throwable e) {
                Log.i(TAG, "onError: ", e);
                System.out.println("Weather Now Error:" + new Gson());
            }
            @Override
            public void onSuccess(Now dataObject) {
                Log.i(TAG, " Weather Now onSuccess: " + new Gson().toJson(dataObject));
                String jsonData = new Gson().toJson(dataObject);
                String weather = null, temperature = null,time = null;
                StringBuilder loc = new StringBuilder("");
                if (dataObject.getStatus().equals("ok")) {
                    String JsonNow = new Gson().toJson(dataObject.getNow());
                    String JsonLoc = new Gson().toJson(dataObject.getBasic());
                    String JsonTime = new Gson().toJson(dataObject.getUpdate());
                    JSONObject jsonObject = null;
                    JSONObject jsonGetBasic = null;
                    JSONObject jsonGetUpdate = null;
                    try {
                        jsonObject = new JSONObject(JsonNow);
                        jsonGetBasic = new JSONObject(JsonLoc);
                        jsonGetUpdate = new JSONObject(JsonTime);
                        weather = jsonObject.getString("cond_txt");
                        temperature = jsonObject.getString("tmp");
                        time = jsonGetUpdate.getString("loc");
                        loc.append("当前位于"+jsonGetBasic.getString("admin_area")+"省"+jsonGetBasic.getString("parent_city")+"市");
                    } catch (JSONException e) {
                        e.printStackTrace();
                    }
                } else {
                    Toast.makeText(MainActivity.this, "有错误", Toast.LENGTH_SHORT).show();
                    return;
                }
                StringBuilder Show = new StringBuilder("");
                String wendu2 = temperature + "℃";
                Show.append(loc+detail+","+"当前天气："+ weather+","+"当前温度：" + wendu2+","+"更新于："+time);
                AddChat(String.valueOf(Show),1);
                startAuto(String.valueOf(Show));
            }
        });
    }
}